package drds.global_transaction.transaction_coordinator.store;

import drds.global_transaction.transaction_coordinator.transaction_session.BranchTransactionSession;
import drds.global_transaction.transaction_coordinator.transaction_session.GlobalTransactionSession;
import lombok.Getter;
import lombok.Setter;

import java.nio.ByteBuffer;

public class TransactionWriteStore implements SessionStorable
{
	@Setter
	@Getter
	private SessionStorable sessionRequest;
	@Setter
	@Getter
	private OperationType operationType;

	public TransactionWriteStore()
	{
	}

	public TransactionWriteStore(SessionStorable sessionRequest, OperationType operationType)
	{
		this.sessionRequest = sessionRequest;
		this.operationType = operationType;
	}

	@Override
	public void decode(byte[] src)
	{
		ByteBuffer byteBuffer = ByteBuffer.wrap(src);
		byte[] sessionRequestBytes = new byte[src.length - 1];
		byteBuffer.get(sessionRequestBytes);
		byte operationTypeCodeByte = byteBuffer.get();
		this.operationType = OperationType.getLogOperationByCode(operationTypeCodeByte);
		SessionStorable sessionStorable = getSessionInstanceByOperation(this.operationType);
		sessionStorable.decode(sessionRequestBytes);
		this.sessionRequest = sessionStorable;
	}

	@Override
	public byte[] encode()
	{
		byte[] sessionRequestBytes = this.sessionRequest.encode();
		byte operationTypeCodeByte = this.getOperationType().getCode();
		int length = sessionRequestBytes.length + 1;
		byte[] bytes = new byte[length];
		ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
		byteBuffer.put(sessionRequestBytes);
		byteBuffer.put(operationTypeCodeByte);
		return bytes;
	}

	private SessionStorable getSessionInstanceByOperation(OperationType operationType)
	{
		SessionStorable sessionStorable = null;
		switch (operationType)
		{
		case add_global_transaction:
		case update_global_transaction:
		case remove_global_transaction:
			sessionStorable = new GlobalTransactionSession();
			break;
		case add_branch_transaction:
		case update_branch_transaction:
		case remove_branch_transaction:
			sessionStorable = new BranchTransactionSession();
			break;

		}
		return sessionStorable;
	}
}
